﻿using System;
using System.Collections.Generic;
using System.Linq;
using Gp.Scripts.Data;
using Gp.Scripts.Data.Skills;
using Gp.Scripts.Core;
using Gp.Scripts.Core.Unit;
using QFramework;
using UnityEngine;

namespace Gp.Scripts.Core {
    public class RulesModel
    {
        private readonly Dictionary<Type, IGameAction> _ruleMap = new();

        public BasicRuleConfig BasicRuleConfig { get; set; }


        public SkillEntityConfig MoveActionEntityConfigEntityConfig { get; set; }

        public SkillEntityConfig WeaponAttackEntityConfigEntityConfig { get; set; }

        public ConfigWeapon DefaultWeapon { get; set; }


        private readonly Dictionary<Type, BaseEntityConfigObject> _dataMap;


        private UnitPrefabEntityConfig[] _playerTeams;

        public UnitPrefabEntityConfig[] PlayerFormation {
            get {
                var res = _playerTeams ?? BasicRuleConfig.playerCombatantPreset.presets.ToArray();
                Array.Resize(ref res, 4);
                return res;
            }
            set => _playerTeams = value;
        }


        public RulesModel(Dictionary<Type, BaseEntityConfigObject> dataMap) {
            this._dataMap = dataMap;
        }


        public void BindAction(IGameAction action) {
            action.InitAction();
            _ruleMap[action.EntityType] = action;
        }


        public IActionResult HandleAction<T>(T entity, IEnumerable<WeakRuleWrapper<T>> rules = null)
            where T : class, IActionRequest {
            // 参数校验
            List<WeakRuleWrapper<T>> list = new List<WeakRuleWrapper<T>>(GetRules<T>());
            if (rules != null) {
                list.AddRange(rules);
            }

            var atkAction = new AttackAction();
            atkAction.InitAction();
            

            // 获取额外规则
            return atkAction.RuleGroup.DoRules(entity as AttackActionRequest);
        }


        private readonly Dictionary<Type, List<IWeakRuleWrapper>> _ruleWrappers = new();


        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="rule"></param>
        /// <typeparam name="T"></typeparam>
        public void RegisterRule<T>(WeakRuleWrapper<T> rule) where T : class, IActionRequest {
            if (!_ruleWrappers.TryGetValue(typeof(T), out var list)) {
                list = new List<IWeakRuleWrapper>();
            }

            list.Add(rule);
            _ruleWrappers[typeof(T)] = list;
        }


        /// <summary>
        /// 注销
        /// </summary>
        /// <param name="rule"></param>
        public void UnRegisterRule(IWeakRuleWrapper rule) {
            if (!_ruleWrappers.TryGetValue(rule.EntityType, out var list)) {
                return;
            }

            list.RemoveAll(i => i == rule);
        }


        private IEnumerable<WeakRuleWrapper<T>> GetRules<T>() where T : class, IActionRequest {
            return _ruleWrappers.TryGetValue(typeof(T), out var list)
                ? list.Select(i => i as WeakRuleWrapper<T>).Where(i => i != null)
                : Array.Empty<WeakRuleWrapper<T>>();
        }


        public void ClearRules() {
            _ruleWrappers.Clear();
        }


        public T GetData<T>() where T : BaseEntityConfigObject {
            return _dataMap.GetValueOrDefault(typeof(T), null) as T;
        }


        public BaseEntityConfigObject GetDataById(string id) {
            // return _dataMap.Values.FirstOrDefault(i => i.GetID == id);
            return null;
        }
    }
}